/*
 * File         : pthread.h
 * This file is part of POSIX-RTOS
 * COPYRIGHT (C) 2015 - 2016, DongHeng
 * Change Logs:
 * DATA             Author          Note
 * 2015-11-26       DongHeng        create
 */

#ifndef _PTHREAD_H_
#define _PTHREAD_H_

#include "pthreadtype.h"
#include "errno.h"

/******************************************************************************/

int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void*), void *);
int pthread_setname_np(pthread_t , const char *);
int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
int pthread_attr_setstacksize(pthread_attr_t *, size_t);
int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *);

/******************************************************************************/

/*
 * @brief initialize the mutex
 *
 * @param mutex - point of the mutex
 * @param attr  - attribute of the mutex
 *
 * @return
 *           0 : success
 *     -EAGAIN : lacks resources to initialize the spin lock
 *     -ENOMEM : insufficient memory exists to initialize the lock
 *      -EPERM : the caller does not have the privilege to perform the operation
 *     -EINVAL : the attributes object referenced by attr has the robust mutex
 *               attribute set without the process-shared attribute being set
 *
 * @note it must not return an error code of [-EINTR]
 */
int pthread_mutex_init(pthread_mutex_t *RESTRICT mutex,
        const pthread_mutexattr_t *RESTRICT attr);

/*
 * @brief destroy the mutex
 *
 * @param mutex - point of the mutex
 *
 * @return
 *           0 : success
 *     -EINVAL : the mutex is not initialized yet
 *      -EBUSY : the mutex is operated by other thread
 *
 * @note it must not return an error code of [-EINTR]
 */
int pthread_mutex_destroy(pthread_mutex_t *mutex);

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

/******************************************************************************/

/*
 * @brief initialize the spin lock
 *
 * @param spinlock - the point of the spin lock
 * @param pshared  - the spin lock will be shared by process if pshared is 0
 *
 * @return       
 *           0 : success
 *     -EAGAIN : lacks resources to initialize the spin lock
 *     -ENOMEM : insufficient memory exists to initialize the lock
 * 
 * @note it must not return an error code of [-EINTR] 
 */
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

/*
 * @brief take the spin lock
 *
 * @param lock - the point of the spin lock
 *
 * @return
 *           0 : success
 *    -EDEADLK : deadlock condition was detected
 */
int pthread_spin_lock(pthread_spinlock_t *lock);

/*
 * @brief try to take the spin lock and return the result
 *
 * @param lock - the point of the spin lock
 *
 * @return
 *           0 : success
 *      -EBUSY : a thread currently holds the lock
 */
int pthread_spin_trylock(pthread_spinlock_t *lock);

/*
 * @brief try to release the spin lock and return the result
 *
 * @param lock - the point of the spin lock
 *
 * @return
 *           0 : success
 *      -EBUSY : a thread currently operates the lock
 *
 * @note it must not return an error code of [-EINTR] 
 */
int pthread_spin_unlock(pthread_spinlock_t *lock);

/*
 * @brief destroy the spinlock
 *
 * @param lock - the point of the spin lock
 *
 * @return
 *           0 : success
 *      -EBUSY : a thread currently operates the lock
 */
int pthread_spin_destroy(pthread_spinlock_t *spinlock);

#endif
